package push.tools.service.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import push.tools.service.constant.ApiUrl;
import push.tools.service.entity.CaseBean;
import push.tools.service.entity.push.PushTaskBean;
import push.tools.service.entity.push.RecordsBean;
import push.tools.service.service.egova.AuthenticationService;
import push.tools.service.service.egova.PreDataService;
import push.tools.service.service.egova.PullCaseService;
import push.tools.service.service.egova.SupportCaseService;
import push.tools.service.service.qycg.CookieService;
import push.tools.service.service.qycg.PushCaseService;
import push.tools.service.service.task.TaskLogService;
import push.tools.service.utils.TimeUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 推送案件服务
 */
@Service
public class PushTaskService {
    private static final Logger logger = LoggerFactory.getLogger(PushTaskService.class);

    @Autowired
    public AuthenticationService authenticationService;

    @Autowired
    public PullCaseService pullCaseService;

    @Autowired
    public SupportCaseService supportCaseService;

    @Autowired
    public PreDataService preDataService;

    @Autowired
    public CookieService cookieService;

    @Autowired
    public PushCaseService pushCaseService;

    @Autowired
    public TaskLogService taskLogService;

    @Async
    public void executeTask(String pushId, String startTime, String endTime) {
        try {
            taskLogService.newTaskLog(pushId, "admin", "001", "开始拉取案件:" + startTime + "至" + endTime);
            // 1、获取token
            String token = authenticationService.getToken();
            taskLogService.addTaskLog(pushId, "001", "获取英德城管token：" + token);
            // 2、并发拉取两类案件
            CompletableFuture<List<CaseBean>> selfDisposeFuture = CompletableFuture.supplyAsync(() -> {
                // 自行处置案件
                return pullCaseService.getCaseList("自行处置", token, startTime, endTime, ApiUrl.selfDispose);
            });
            CompletableFuture<List<CaseBean>> specialtyDisposeFuture = CompletableFuture.supplyAsync(() -> {
                // 专业部门处置案件
                return pullCaseService.getCaseList("专业部门", token, startTime, endTime, ApiUrl.specialtyDispose);
            });
            // 等待并合并结果
            List<CaseBean> selfDisposeList = selfDisposeFuture.join();
            List<CaseBean> specialtyDisposeList = specialtyDisposeFuture.join();
            taskLogService.addTaskLog(pushId, "001", "等待拉取自行处置案件：" + selfDisposeList.size() + "条");
            taskLogService.addTaskLog(pushId, "001", "等待拉取专业部门案件：" + specialtyDisposeList.size() + "条");
            if (selfDisposeList.isEmpty() && specialtyDisposeList.isEmpty()) {
                taskLogService.addTaskLog(pushId, "000", "该时间段内案件数为0条,结束推送流程");
                return;
            }
            taskLogService.addTaskLog(pushId, "001", "正在获取补充案件中......");
            // 3、补充专业部门案件信息
            List<CompletableFuture<Void>> replenishFutures = new ArrayList<>();
            for (CaseBean caseBean : specialtyDisposeList) {
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    // 补充案件
                    supportCaseService.replenish(caseBean);
                });
                replenishFutures.add(future);
            }
            // 等待并合并结果
            CompletableFuture.allOf(replenishFutures.toArray(new CompletableFuture[0])).join();

            // 合并所有案件
            List<CaseBean> allCaseList = new ArrayList<>();
            allCaseList.addAll(selfDisposeList);
            allCaseList.addAll(specialtyDisposeList);
            taskLogService.addTaskLog(pushId, "001", "结束拉取案件，开始推送共有" + allCaseList.size() + "条案件");
            String cookie = cookieService.getCookie(); //拿到cookie
            taskLogService.addTaskLog(pushId, "001", "开始推送，获取清远城管cookie：" + cookie);
            // 并发推送所有案件
            List<CompletableFuture<Void>> pushFutures = new ArrayList<>();
            for (CaseBean caseBean : allCaseList) {
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    CaseBean handleBean = preDataService.handle(caseBean); //数据前置处理
                    pushCaseService.push(handleBean, cookie); //推送清远城管
                });
                pushFutures.add(future);
            }
            CompletableFuture.allOf(pushFutures.toArray(new CompletableFuture[0])).join();
            taskLogService.addTaskLog(pushId, "000", "推送流程结束");
        } catch (Exception e) {
            logger.error("任务执行失败，任务ID: {}", pushId, e);
            taskLogService.addTaskLog(pushId, "000", "推送流程异常，pushId：" + pushId + "异常信息：" + e.getMessage());
        }
    }
}